from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from io import BytesIO
import pandas as pd
from django.http import HttpResponse
import logging
import json
from django.conf import settings
import os
import uuid
from ..tasks import import_customers_task

from ..models import Customer, Order
from ..serializers import CustomerSerializer

logger = logging.getLogger(__name__)

class CustomerViewSet(viewsets.ModelViewSet):
    """客户视图集"""
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer
    
    def get_queryset(self):
        """实现查询过滤"""
        queryset = super().get_queryset()
        
        # 获取查询参数
        customer_name = self.request.query_params.get('customer_name', None)
        
        # 记录请求参数
        logger.info(f"CustomerViewSet查询参数: customer_name={customer_name}")
        
        # 应用过滤条件
        if customer_name:
            queryset = queryset.filter(customer_name__icontains=customer_name)
            
        return queryset
    
    def list(self, request, *args, **kwargs):
        """重写list方法，确保返回一致的格式"""
        queryset = self.filter_queryset(self.get_queryset())
        
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            response = self.get_paginated_response(serializer.data)
        else:
            serializer = self.get_serializer(queryset, many=True)
            response = Response(serializer.data)
        
        # 记录返回的数据格式
        logger.info(f"CustomerViewSet list返回数据格式: {type(response.data)}")
        
        return response
    
    def retrieve(self, request, *args, **kwargs):
        """重写retrieve方法，添加调试日志"""
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        response = Response(serializer.data)
        
        # 记录返回的数据
        logger.info(f"CustomerViewSet retrieve返回数据: {json.dumps(serializer.data, default=str)}")
        
        return response
    
    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出客户数据为Excel"""
        queryset = self.get_queryset()
        
        # 创建一个空的DataFrame
        df = pd.DataFrame()
        
        # 添加所需列
        df['客户ID'] = [customer.id for customer in queryset]
        df['客户名称'] = [customer.customer_name for customer in queryset]
        df['客户来源'] = [customer.get_customer_source_display() for customer in queryset]
        df['手机号码'] = [customer.phone_number for customer in queryset]
        
        # 添加关联订单数量
        order_counts = []
        for customer in queryset:
            order_count = Order.objects.filter(customer_name=customer).count()
            order_counts.append(order_count)
        df['订单数量'] = order_counts
        
        # 创建一个字节流
        output = BytesIO()
        
        # 将DataFrame写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='客户数据', index=False)
            
        # 设置文件指针到开始
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=客户数据.xlsx'
        
        return response
        
    @action(detail=False, methods=['get'])
    def import_template(self, request):
        """下载客户导入模板"""
        # 创建一个空的DataFrame
        df = pd.DataFrame(columns=['客户名称*', '客户来源', '手机号码'])
        
        # 添加示例数据行
        df.loc[0] = ['示例客户名称(必填且唯一)', 'Newbe工作室', '13800138000']
        
        # 添加说明行
        df.loc[1] = ['', '可选值: Newbe工作室, 纽币德信息科技, 官方网站, 其它', '']
        
        # 创建一个字节流
        output = BytesIO()
        
        # 将DataFrame写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='客户导入模板', index=False)
            
            # 获取工作簿和工作表
            workbook = writer.book
            worksheet = writer.sheets['客户导入模板']
            
            # 添加格式
            header_format = workbook.add_format({
                'bold': True,
                'bg_color': '#D9EAD3',
                'border': 1
            })
            
            # 设置列宽
            worksheet.set_column('A:A', 25)
            worksheet.set_column('B:B', 25)
            worksheet.set_column('C:C', 20)
            
            # 应用格式到表头
            for col_num, value in enumerate(df.columns.values):
                worksheet.write(0, col_num, value, header_format)
                
            # 添加说明
            notes_format = workbook.add_format({
                'italic': True,
                'font_color': '#808080'
            })
            
            # 在底部添加说明
            worksheet.write(4, 0, '注意事项:', workbook.add_format({'bold': True}))
            worksheet.write(5, 0, '1. 带*的字段为必填项', notes_format)
            worksheet.write(6, 0, '2. 客户名称必须唯一，系统会自动检查是否存在重复', notes_format)
            worksheet.write(7, 0, '3. 客户来源若留空，默认为"其它"', notes_format)
            worksheet.write(8, 0, '4. 如果导入的客户已经存在于系统中，将会自动跳过，不会覆盖原有客户信息', notes_format)
            
        # 设置文件指针到开始
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=客户导入模板.xlsx'
        
        return response
        
    @action(detail=False, methods=['post'])
    def import_data(self, request):
        """导入客户数据"""
        file = request.FILES.get('file')
        if not file:
            return Response({'success': False, 'message': '请上传文件'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 检查文件类型
        if not file.name.endswith(('.xlsx', '.xls')):
            return Response({'success': False, 'message': '只支持Excel文件(.xlsx或.xls)'}, status=status.HTTP_400_BAD_REQUEST)
        
        try:
            # 创建临时目录（如果不存在）
            temp_dir = os.path.join(settings.BASE_DIR, 'temp_uploads')
            os.makedirs(temp_dir, exist_ok=True)
            
            # 保存上传的文件到临时位置
            file_extension = os.path.splitext(file.name)[1]
            temp_filename = f"customer_import_{uuid.uuid4().hex}{file_extension}"
            temp_file_path = os.path.join(temp_dir, temp_filename)
            
            with open(temp_file_path, 'wb+') as destination:
                for chunk in file.chunks():
                    destination.write(chunk)
                    
            logger.info(f"已保存上传文件到临时位置: {temp_file_path}")
            
            # 尝试异步处理文件导入
            try:
                # 启动异步任务
                task = import_customers_task.delay(temp_file_path)
                
                # 返回任务ID
                return Response({
                    'success': True,
                    'message': '已开始处理导入任务，请稍后刷新页面查看结果',
                    'task_id': task.id
                })
            except Exception as task_error:
                # 如果异步任务启动失败，记录错误并回退到同步处理
                logger.warning(f"异步任务启动失败，将使用同步方式处理: {str(task_error)}")
                
                # 直接调用任务函数进行同步处理
                result = import_customers_task(temp_file_path)
                return Response(result)
                
        except Exception as e:
            logger.error(f"导入客户数据出错: {str(e)}")
            # 返回更详细的错误信息
            import traceback
            error_details = traceback.format_exc()
            logger.error(f"详细错误: {error_details}")
            return Response({
                'success': False, 
                'message': f'导入出错: {str(e)}', 
                'details': error_details if settings.DEBUG else '请联系管理员查看日志'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 